home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 26 / AMIGAplus Sonderheft 26 (2000)(Falke)(DE)(Track 1 of 2)[!].iso / Tools / GFX-Viewer / Animviewer / mpegvideo_datatype / mpeggdith.c < prev    next >
C/C++ Source or Header  |  1999-03-29  |  7KB  |  326 lines

  1.  
  2. /*
  3. **
  4. **  $VER: mpeggdith.c 1.11 (2.11.97)
  5. **  mpegvideo.datatype 1.11
  6. **
  7. **  dithering
  8. **
  9. **  Written 1996/1997 by Roland 'Gizzy' Mainz
  10. **
  11. */
  12.  
  13. /* amiga includes */
  14. #include <exec/types.h>
  15.  
  16. /* ansi includes */
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <math.h>
  20.  
  21. /* project includes */
  22. #include "mpegmyassert.h"
  23. #include "mpegvideo.h"
  24. #include "mpegproto.h"
  25.  
  26. /* local prototypes */
  27. static void ConvertColor( UBYTE, UBYTE, UBYTE, struct ColorRegister * );
  28.  
  29.  
  30. /*
  31.  *--------------------------------------------------------------
  32.  *
  33.  * InitColor --
  34.  *
  35.  *      Initialized lum, cr, and cb quantized range value arrays.
  36.  *
  37.  * Results:
  38.  *      None.
  39.  *
  40.  * Side effects:
  41.  *      None.
  42.  *
  43.  *--------------------------------------------------------------
  44.  */
  45.  
  46.  
  47. void InitColor( struct MPEGVideoInstData *mvid )
  48. {
  49.     ULONG i;
  50.  
  51.     for( i = 0UL ; i < LUM_RANGE ; i++ )
  52.     {
  53.       lum_values[ i ] = (((i * 255) / (LUM_RANGE)) + (255 / (LUM_RANGE * 2))) % 255UL;
  54.     }
  55.  
  56.     for( i = 0UL ; i < CR_RANGE ; i++ )
  57.     {
  58.       cr_values[ i ] = (((i * 255) / (CR_RANGE)) + (255 / (CR_RANGE * 2))) % 255UL;
  59.     }
  60.  
  61.     for( i = 0UL ; i < CB_RANGE ; i++ )
  62.     {
  63.       cb_values[ i ] = (((i * 255) / (CB_RANGE)) + (255 / (CB_RANGE * 2))) % 255UL;
  64.     }
  65. }
  66.  
  67.  
  68. /*
  69.  *--------------------------------------------------------------
  70.  *
  71.  * ConvertColor --
  72.  *
  73.  *    Given a l, cr, cb tuple, converts it to r,g,b.
  74.  *
  75.  * Results:
  76.  *    r,g,b values returned in pointers passed as parameters.
  77.  *
  78.  * Side effects:
  79.  *      None.
  80.  *
  81.  *--------------------------------------------------------------
  82.  */
  83.  
  84.  
  85. static
  86. void ConvertColor( UBYTE l, UBYTE cr, UBYTE cb, struct ColorRegister *rgb )
  87. {
  88.     double fl, fcr, fcb, fr, fg, fb;
  89.  
  90.     fl  = (double)l;
  91.     fcr = ((double)cr) - 128.0;
  92.     fcb = ((double)cb) - 128.0;
  93.  
  94.     fr = fl + (1.40200 * fcb);
  95.     fg = fl - (0.71414 * fcb) - (0.34414 * fcr);
  96.     fb = fl + (1.77200 * fcr);
  97.  
  98.     /* Store colors */
  99.     rgb -> red   = (UBYTE)(fr < 0.0)?(0.0):((fr > 255.0)?(255.0):(fr));
  100.     rgb -> green = (UBYTE)(fg < 0.0)?(0.0):((fg > 255.0)?(255.0):(fg));
  101.     rgb -> blue  = (UBYTE)(fb < 0.0)?(0.0):((fb > 255.0)?(255.0):(fb));
  102. }
  103.  
  104.  
  105. /*
  106.  *--------------------------------------------------------------
  107.  *
  108.  * InitDisplay --
  109.  *
  110.  *    Initialized display, sets up colormap, etc.
  111.  *
  112.  * Results:
  113.  *      None.
  114.  *
  115.  * Side effects:
  116.  *      None.
  117.  *
  118.  *--------------------------------------------------------------
  119.  */
  120.  
  121.  
  122. void InitDisplay( struct MPEGVideoInstData *mvid )
  123. {
  124.     long                 ncolors = LUM_RANGE * CB_RANGE * CR_RANGE;
  125.     long                 i,
  126.                          lum_num,
  127.                          cr_num,
  128.                          cb_num;
  129.     struct ColorRegister color;
  130.  
  131.     /* maxpixel will be set up dynamically */
  132.     if( mvid -> mvid_PalettePerFrame )
  133.       return;
  134.  
  135.     if( ncolors > (1UL << anim_depth) )
  136.     {
  137.       verbose_printf( mvid, "truncating colormap from %lu down to %lu colors\n", ncolors, (1UL << anim_depth) );
  138.     }
  139.  
  140. retrycolors:
  141.     for( i = 0L ; i < ncolors ; i++ )
  142.     {
  143.       lum_num = (i / (CR_RANGE * CB_RANGE)) % LUM_RANGE;
  144.       cr_num  = (i / CB_RANGE) % CR_RANGE;
  145.       cb_num  = i % CB_RANGE;
  146.  
  147.       ConvertColor( lum_values[ lum_num ], cr_values[ cr_num ], cb_values[ cb_num ], (&color) );
  148.  
  149.       mappixel[ i ] = SearchColor( mvid, used_colors, (&used_cnt), (1UL << anim_depth), (&color) );
  150.  
  151.       /* color table overflow ? */
  152.       if( (used_cnt >= (1UL << anim_depth)) && (i < (ncolors - 1)) )
  153.       {
  154.         mvid -> mvid_ColorError += 1UL;
  155.         used_cnt = 0UL;
  156.  
  157.         verbose_printf( mvid, "color table overflow, retry with colorerr=%lu\n", (ULONG)(mvid -> mvid_ColorError) );
  158.  
  159.         goto retrycolors;
  160.       }
  161.     }
  162.  
  163.     /* statistics... */
  164.     verbose_printf( mvid, "%lu colors used of %lu possible\n", (ULONG)used_cnt, (ULONG)(1UL << anim_depth) );
  165. }
  166.  
  167.  
  168. /*
  169.  *--------------------------------------------------------------
  170.  *
  171.  * InitGrayDisplay --
  172.  *
  173.  *    Initialized display for gray scale dither.
  174.  *
  175.  * Results:
  176.  *      None.
  177.  *
  178.  * Side effects:
  179.  *      None.
  180.  *
  181.  *--------------------------------------------------------------
  182.  */
  183.  
  184.  
  185. void InitGrayDisplay( struct MPEGVideoInstData *mvid )
  186. {
  187.     ULONG                   i,
  188.                             j,
  189.                             numcolors,
  190.                             fac;
  191.     ULONG                   pixel;
  192.     struct ColorRegister    color;
  193.  
  194.     numcolors  = (1UL << anim_depth);
  195.     fac        = INTDIVR( 255UL, numcolors );
  196.  
  197. retrycolors:
  198.  
  199.     for( i = 0UL ; i < numcolors ; i++ )
  200.     {
  201.       color . red = color . green = color . blue = (i * fac);
  202.  
  203.       pixel = SearchColor( mvid, used_colors, (&used_cnt), (1UL << anim_depth), (&color) );
  204.  
  205.       /* color table overflow ? */
  206.       if( (used_cnt >= (1UL << anim_depth)) && (i < (numcolors - 1)) )
  207.       {
  208.         mvid -> mvid_ColorError += 1UL;
  209.         used_cnt = 0UL;
  210.  
  211.         verbose_printf( mvid, "gray color table overflow, retry with colorerr=%lu\n", (ULONG)(mvid -> mvid_ColorError) );
  212.  
  213.         goto retrycolors;
  214.       }
  215.  
  216.       for( j = 0UL ; j < fac ; j++ )
  217.       {
  218.         mappixel[ (i * fac) + j ] = pixel;
  219.       }
  220.     }
  221.  
  222.     /* statistics... */
  223.     verbose_printf( mvid, "%lu colors used of %lu possible\n", (ULONG)used_cnt, (ULONG)(1UL << anim_depth) );
  224. }
  225.  
  226.  
  227. /*
  228.  *--------------------------------------------------------------
  229.  *
  230.  * InitHAMDisplay --
  231.  *
  232.  *    Initialized display for HAM dither.
  233.  *
  234.  * Results:
  235.  *      None.
  236.  *
  237.  * Side effects:
  238.  *      None.
  239.  *
  240.  *--------------------------------------------------------------
  241.  */
  242.  
  243.  
  244. void InitHAMDisplay( struct MPEGVideoInstData *mvid )
  245. {
  246.     ULONG i  = 0UL;
  247.     ULONG value;
  248.  
  249.     switch( anim_depth )
  250.     {
  251.       case 8: /* HAM-8 */
  252.       {
  253.           for( i = 0UL ; i < 64UL ; i++ )
  254.           {
  255.             value = (255UL * i) / 63UL;
  256.  
  257.             used_colors[ i ] . red = used_colors[ i ] . green = used_colors[ i ] . blue = value;
  258.           }
  259.       }
  260.           break;
  261.  
  262.       case 6: /* HAM-6 */
  263.       {
  264.           for( i = 0UL ; i < 16UL ; i++ )
  265.           {
  266.             value = (255UL * i) / 15UL;
  267.  
  268.             used_colors[ i ] . red = used_colors[ i ] . green = used_colors[ i ] . blue = value;
  269.           }
  270.       }
  271.           break;
  272.     }
  273.  
  274.     used_cnt = i;
  275.  
  276.     /* statistics... */
  277.     verbose_printf( mvid, "HAM %lu colors used of %lu possible\n", (ULONG)used_cnt, (ULONG)(1UL << (anim_depth - 2)) );
  278. }
  279.  
  280.  
  281. /*
  282.  *--------------------------------------------------------------
  283.  *
  284.  * ExecuteDisplay --
  285.  *
  286.  *    Actually displays display plane in previously created window.
  287.  *
  288.  * Results:
  289.  *    None.
  290.  *
  291.  * Side effects:
  292.  *    None.
  293.  *
  294.  *--------------------------------------------------------------
  295.  */
  296.  
  297.  
  298. void ExecuteDisplay( struct MPEGVideoInstData *mvid, VidStream *vid_stream )
  299. {
  300.     if( mvid -> mvid_SkipFrames )
  301.     {
  302.       /* Skip n pictures (Exept the first one) */
  303.       if( (totNumFrames % (mvid -> mvid_SkipFrames)) && (totNumFrames > 1UL) )
  304.       {
  305.         if( mvid -> mvid_IndexScan )
  306.         {
  307.           verbose_printf( mvid, "skipping frame %ld\n", totNumFrames );
  308.         }
  309.  
  310.         /* Add empty frame node (for sound etc.) */
  311.         AddFrame( mvid, NULL, NULL );
  312.  
  313.         return;
  314.       }
  315.     }
  316.  
  317.     if( mvid -> mvid_IndexScan )
  318.     {
  319.       verbose_printf( mvid, "loading frame %ld\n", totNumFrames );
  320.     }
  321.  
  322.     StoreFrame( mvid, (vid_stream -> current -> display) );
  323. }
  324.  
  325.  
  326.